//package com.ctrip.corp.obt.shard.sql.parser.optimize;
//
//
//import com.ctrip.corp.obt.generic.utils.CollectionUtils;
//import com.ctrip.corp.obt.generic.utils.StringPool;
//import com.ctrip.corp.obt.shard.sql.parser.ISqlParser;
//import com.ctrip.corp.obt.shard.sql.parser.SqlInfo;
//import com.ctrip.corp.obt.shard.utils.SqlParserUtils;
//import lombok.AllArgsConstructor;
//import lombok.Data;
//import lombok.NoArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import net.sf.jsqlparser.expression.Alias;
//import net.sf.jsqlparser.expression.Expression;
//import net.sf.jsqlparser.expression.Function;
//import net.sf.jsqlparser.expression.LongValue;
//import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
//import net.sf.jsqlparser.parser.CCJSqlParserUtil;
//import net.sf.jsqlparser.schema.Table;
//import net.sf.jsqlparser.statement.select.Distinct;
//import net.sf.jsqlparser.statement.select.GroupByElement;
//import net.sf.jsqlparser.statement.select.Join;
//import net.sf.jsqlparser.statement.select.OrderByElement;
//import net.sf.jsqlparser.statement.select.PlainSelect;
//import net.sf.jsqlparser.statement.select.Select;
//import net.sf.jsqlparser.statement.select.SelectExpressionItem;
//import net.sf.jsqlparser.statement.select.SelectItem;
//import org.apache.ibatis.reflection.MetaObject;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Optional;
//
///**
// * Count Optimize sqlParser
// *
// * @author marco.zheng
// * @since 2017-06-20
// */
//@Data
//@Slf4j
//@NoArgsConstructor
//@AllArgsConstructor
//public class CountOptimizeSqlParser implements ISqlParser {
//    private static final List<SelectItem> COUNT_SELECT_ITEM = countSelectItem();
//
//    private boolean optimizeJoin = false;
//
//    /**
//     * 获取sqlParser中count的SelectItem
//     */
//    private static List<SelectItem> countSelectItem() {
//        Function function = new Function();
//        function.setName("COUNT");
//        List<Expression> expressions = new ArrayList<>();
//        LongValue longValue = new LongValue(1);
//        ExpressionList expressionList = new ExpressionList();
//        expressions.add(longValue);
//        expressionList.setExpressions(expressions);
//        function.setParameters(expressionList);
//        List<SelectItem> selectItems = new ArrayList<>();
//        SelectExpressionItem selectExpressionItem = new SelectExpressionItem(function);
//        selectItems.add(selectExpressionItem);
//        return selectItems;
//    }
//
//    @Override
//    public SqlInfo parser(MetaObject metaObject, String sql) {
//        if (log.isDebugEnabled()) {
//            log.debug("CountOptimizeSqlParser sql=" + sql);
//        }
//        SqlInfo sqlInfo = SqlInfo.newInstance();
//        try {
//            Select selectStatement = (Select) CCJSqlParserUtil.parse(sql);
//            PlainSelect plainSelect = (PlainSelect) selectStatement.getSelectBody();
//            Distinct distinct = plainSelect.getDistinct();
//            GroupByElement groupBy = plainSelect.getGroupBy();
//            List<OrderByElement> orderBy = plainSelect.getOrderByElements();
//
//            // 添加包含groupBy 不去除orderBy
//            if (null == groupBy && CollectionUtils.isNotEmpty(orderBy)) {
//                plainSelect.setOrderByElements(null);
//                sqlInfo.setOrderBy(false);
//            }
//            // selectItems contains #{} ${}, which will be translated to ?, and it may be in a function: power(#{myInt},2)
//            for (SelectItem item : plainSelect.getSelectItems()) {
//                if (item.toString().contains(StringPool.QUESTION_MARK)) {
//                    return sqlInfo.setSql(SqlParserUtils.getOriginalCountSql(selectStatement.toString()));
//                }
//            }
//            // 包含 distinct、groupBy不优化
//            if (distinct != null || null != groupBy) {
//                return sqlInfo.setSql(SqlParserUtils.getOriginalCountSql(selectStatement.toString()));
//            }
//            // 包含 join 连表,进行判断是否移除 join 连表
//            List<Join> joins = plainSelect.getJoins();
//            if (optimizeJoin && CollectionUtils.isNotEmpty(joins)) {
//                boolean canRemoveJoin = true;
//                String whereS = Optional.ofNullable(plainSelect.getWhere()).map(Expression::toString).orElse(StringPool.EMPTY);
//                for (Join join : joins) {
//                    if (!join.isLeft()) {
//                        canRemoveJoin = false;
//                        break;
//                    }
//                    Table table = (Table) join.getRightItem();
//                    String str = Optional.ofNullable(table.getAlias()).map(Alias::getName).orElse(table.getName()) + StringPool.DOT;
//                    String onExpressionS = join.getOnExpression().toString();
//                    /* 如果 join 里包含 ?(代表有入参) 或者 where 条件里包含使用 join 的表的字段作条件,就不移除 join */
//                    if (onExpressionS.contains(StringPool.QUESTION_MARK) || whereS.contains(str)) {
//                        canRemoveJoin = false;
//                        break;
//                    }
//                }
//                if (canRemoveJoin) {
//                    plainSelect.setJoins(null);
//                }
//            }
//            // 优化 SQL
//            plainSelect.setSelectItems(COUNT_SELECT_ITEM);
//            return sqlInfo.setSql(selectStatement.toString());
//        } catch (Throwable e) {
//            // 无法优化使用原 SQL
//            return sqlInfo.setSql(SqlParserUtils.getOriginalCountSql(sql));
//        }
//    }
//}
